package com.lwm.service.impl;

import cn.hutool.core.util.IdUtil;
import com.lwm.domain.ResponseResult;
import com.lwm.domain.SalesContract;
import com.lwm.domain.SalesContractMaterials;
import com.lwm.dto.PageParams;
import com.lwm.dto.SalesContractDto;
import com.lwm.mapper.SalesContractMapper;
import com.lwm.service.SalesContractMaterialsService;
import com.lwm.service.SalesContractService;
import com.lwm.service.SalesOrderService;
import com.lwm.utils.Code;
import com.lwm.utils.HintMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SalesContractServiceImpl implements SalesContractService {
    @Resource
    private SalesOrderService salesOrderService;
    @Resource
    private SalesContractMapper salesContractMapper;
    @Resource
    private  SalesContractMaterialsService salesContractMaterialsService;

    @Override
    public ResponseResult<List<SalesContract>> page(SalesContractDto salesContractDto) {
        if(salesContractDto.getSize() == null) salesContractDto.setSize(10);
        if(salesContractDto.getPage() == null) salesContractDto.setPage(1);
        // 拿到总条数
        Long total = salesContractMapper.getTotal(salesContractDto);
        // 拿到最大页码
        Double maxPage = Math.ceil(Double.valueOf(total) / Double.valueOf(salesContractDto.getSize()));
        // 求当前页码
        Integer currentPage = maxPage.intValue() < salesContractDto.getPage() ? maxPage.intValue() : salesContractDto.getPage();
        currentPage = currentPage <= 0 ? 1 : currentPage;
        // 求开始的页码
        Integer startPage = (currentPage - 1) * salesContractDto.getSize();
        salesContractDto.setPage(startPage);
        HashMap<SalesContract, List<Long>> longListHashMap = new HashMap<>();
        // 查询销售合同
        List<SalesContract> pageList = salesContractMapper.getPage(salesContractDto);
        // 遍历去重和 解析售合同、物料档案关联id key: 销售合同 value: 关联表id列表
        for (SalesContract salesContract : pageList) {
            List<Long> longs = longListHashMap.get(salesContract);
            if(longs == null || longs.size() == 0) {
                List<Long> ids = new ArrayList<>();
                ids.add(salesContract.getMaterialsId());
                longListHashMap.put(salesContract, ids);
            } else {
                longs.add(salesContract.getMaterialsId());
                longListHashMap.put(salesContract, longs);
            }
        }

        // 从map解析value查询物料信息保存在key的销售合同 并映射成list
        List<SalesContract> resultPageList = new ArrayList<>();
        longListHashMap.forEach((key, value) -> {
            List<SalesContractMaterials> list = salesContractMaterialsService.getList(value);
            key.setSalesContractMaterials(list);
            resultPageList.add(key);
        });

        List<SalesContract> salesContracts = null;
        if((startPage + salesContractDto.getSize()) > resultPageList.size()) {
            salesContracts = resultPageList.subList(startPage, resultPageList.size());
        } else {
            salesContracts = resultPageList.subList(startPage, startPage + salesContractDto.getSize());
        }
        //遍历resultPageList 拿到销售订单id 查询销售订单数据保存到销售合同
        salesContracts.forEach(item -> {
            item.setSalesOrder(salesOrderService.getById(item.getOrderNumber()));
        });

        // 返回数据
        PageParams<Object> objectPageParams = new PageParams<>(currentPage, salesContractDto.getSize(), total.intValue(), salesContracts);
        return new ResponseResult(Code.GET_OK, HintMessage.GET_OK_HINT, objectPageParams);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Object> save(SalesContract salesContract) {
        if(salesContract.getIsDeleted() == null) salesContract.setIsDeleted(0);
        salesContract.setId(IdUtil.getSnowflakeNextId());
        // 添加销售合同
        salesContractMapper.Insert(salesContract);
        List<SalesContractMaterials> salesContractMaterials = salesContract.getSalesContractMaterials();
        salesContractMaterials.forEach(item -> item.setSalesContractId(salesContract.getId()));
        // 批量添加销售合同和物料的关系数据
        salesContractMaterialsService.batchInsert(salesContractMaterials);
        return new ResponseResult<>(Code.SAVE_OK, HintMessage.SAVE_OK_HINT);
    }

    @Override
    @Transactional
    public ResponseResult<Object> remove(List<Long> ids) {
        // 批量删除销售合同
        salesContractMapper.batchRemove(ids);
        // 批量删除销售合同 和 物料关系表
        ids.forEach(item -> {
            salesContractMaterialsService.removeBySalesContractId(item);
        });
        return new ResponseResult<>(Code.DELETE_OK, HintMessage.REMOVE_OK_HINT);
    }

    @Override
    @Transactional
    public ResponseResult<Object> update(SalesContract salesContract) {
        if(salesContract.getId() == null) {
            return new ResponseResult<>(Code.UPDATE_ERR, HintMessage.EDIT_ERR_HINT);
        }
        // 更具id更新销售合同
        salesContractMapper.updateById(salesContract);
        // 删除原本的销售合同和物料表的关系
        salesContractMaterialsService.removeBySalesContractId(salesContract.getId());
        // 重新天添加销售合同和物料表关系
        List<SalesContractMaterials> salesContractMaterials = salesContract.getSalesContractMaterials();
        salesContractMaterials.forEach(item -> item.setSalesContractId(salesContract.getId()));
        salesContractMaterialsService.batchInsert(salesContractMaterials);

        return new ResponseResult<>(Code.UPDATE_OK, HintMessage.EDIT_OK_HINT);
    }
}
